# 已成功

import re
import os
import subprocess
import tree_sitter_related as ts






# def merge_intervals(list_place):
#     # 先按移动前的起点进行排序
#     sorted_intervals = sorted(list_place, key=lambda x: x[0])
#
#     merged_intervals = []
#
#     for current in sorted_intervals:
#         if not merged_intervals:
#             # 如果合并列表为空，添加第一个区间
#             merged_intervals.append(current)
#         else:
#             # 检查当前区间 是否与合并后的最后一个区间重叠或相邻
#             last = merged_intervals[-1]
#             if current[0] <= last[1]:  # 有重叠
#                 # 合并区间
#                 new_interval = (last[0], max(last[1], current[1]))
#                 merged_intervals[-1] = new_interval  # 更新最后一个区间
#             else:
#                 # 没有重叠，直接添加到合并区间
#                 merged_intervals.append(current)
#
#                 # 从后往前排序
#     merged_intervals.sort(key=lambda x: (x[0], x[1]), reverse=True)
#
#     return merged_intervals
#
#
#
# def remove_cfg_test(rust_code):
#     # 用来计数满足条件的子节点
#     root_node = ts.get_root_node(rust_code)
#     for i, child in enumerate(root_node.children):
#         # 如果满足条件，进行计数
#         if child.type == 'attribute_item' and child.text.decode('utf-8') == '#[cfg(test)]':
#             start_index = child.start_byte
#             # 找到#[test]下方的第一个函数
#             while i < len(root_node.children) and root_node.children[i].type not in ['function_item', 'mod_item']:
#                 i += 1
#             if i >= len(root_node.children):
#                 continue
#             # 找到测试函数
#             # function_name = ts.get_function_name(root_node.children[i])
#             end_index = root_node.children[i].end_byte
#             rust_code = rust_code[:start_index] + rust_code[end_index:]
#         remove_cfg_test(rust_code)
#     return rust_code



# def get_test_place(root_node):
#     # 用来计数满足条件的子节点
#     list_place = []
#     for i, child in enumerate(root_node.children):
#         # 如果满足条件，进行计数
#         if child.type == 'attribute_item' and child.text.decode('utf-8') == '#[test]':
#             start_index = child.start_byte
#             # 找到#[test]下方的第一个函数
#             while i < len(root_node.children) and root_node.children[i].type != 'function_item':
#                 i += 1
#             if i >= len(root_node.children):
#                 continue
#             # 找到测试函数
#             function_name = ts.get_function_name(root_node.children[i])
#             end_index = root_node.children[i].end_byte
#             if end_index == 2537:
#                 ts.print_ast(root_node.children[i], 4)
#
#             list_place.append((start_index, end_index))
#
#         # 递归调用，累加子节点的计数
#         list_place.extend(get_test_place(child))
#     return list_place
#
#
#
# def get_cfg_test_place(root_node):
#     # 用来计数满足条件的子节点
#     list_place = []
#     for i, child in enumerate(root_node.children):
#         # 如果满足条件，进行计数
#         if child.type == 'attribute_item' and child.text.decode('utf-8') == '#[cfg(test)]':
#             start_index = child.start_byte
#             # 找到#[test]下方的第一个函数
#             while i < len(root_node.children) and root_node.children[i].type not in ['function_item', 'mod_item']:
#                 i += 1
#             if i >= len(root_node.children):
#                 continue
#             # 找到测试函数
#             function_name = ts.get_function_name(root_node.children[i])
#             end_index = root_node.children[i].end_byte
#             # if end_index == 2537:
#             #     ts.print_ast(root_node.children[i], 4)
#
#             list_place.append((start_index, end_index))
#
#         # 递归调用，累加子节点的计数
#         list_place.extend(get_cfg_test_place(child))
#     return list_place


















"""
input: .rs文件
output: mod tests{...}(str)，没有返回空字符串
"""
def extract_tests_module(file_path):
    try:
        tests_module = ''
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 正则表达式匹配 mod tests {，考虑空格
        pattern = r'mod tests\s*{'
        match = re.search(pattern, content)

        if match:
            start_index = match.start()
            left_index = start_index
            # start_index对应{
            while content[left_index] != "{":
                left_index += 1

            # 从找到的位置开始查找对应的大括号
            brace_count = 0
            end_index = start_index

            for i in range(left_index, len(content)):
                if content[i] == '{':
                    brace_count += 1
                elif content[i] == '}':
                    brace_count -= 1

                # 当brace_count减至0时，表示找到了匹配的右大括号
                if brace_count == 0:
                    end_index = i
                    break

            tests_module = content[start_index:end_index + 1]

        return tests_module

    except FileNotFoundError:
        print(f"文件 {file_path} 未找到。")
    except Exception as e:
        print(f"发生错误: {e}")




'''
input: rs文件路径
output: 没有返回值，删除文件的# [cfg(test)]标记下面的模块
'''
def remove_cfg_test(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 正则表达式匹配 #[cfg(test)]
        pattern_cfg = r'#\s*\[cfg\(test\)\]'
        # pattern_cfg = r'^\s*#\s*\[cfg\(test\)\]'

        # 遍历内容，找到所有的 #[cfg(test)] 标记
        matches = list(re.finditer(pattern_cfg, content))

        if not matches:
            return

        # 如果找到了 #[cfg(test)]，进行处理
        for match in matches:
            start_index = match.start()
            if start_index > 0 and content[start_index - 1] != '\n':
                continue

            # 从 #[cfg(test)] 位置开始，寻找第一个 "{"，并继续查找匹配的 "}"
            brace_count = 0
            left_index = start_index

            # 跳过 #[cfg(test)] 后面的空白字符
            left_index = content.find("{", left_index)

            if left_index == -1:
                continue  # 如果没有找到 '{'，跳过此标记

            # 从第一个 '{' 开始查找匹配的 '}'
            for i in range(left_index, len(content)):
                if content[i] == '{':
                    brace_count += 1
                elif content[i] == '}':
                    brace_count -= 1

                # 当 brace_count 为 0 时，找到了匹配的 '}'
                if brace_count == 0:
                    right_index = i
                    break
            else:
                continue  # 如果没有找到匹配的 '}'，跳过此标记

            # 删除 #[cfg(test)] 和 { ... } 块的内容
            content = content[:start_index] + content[right_index + 1:]

            # 删除后需要更新matches
            matches = list(re.finditer(pattern_cfg, content))


        # 将删除后的内容写回原文件
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(content)

        print(f"已删除文件 {file_path} 中的 #[cfg(test)] 块及其内容。")

    except FileNotFoundError:
        print(f"文件 {file_path} 未找到。")
    except Exception as e:
        print(f"发生错误: {e}")











def remove_single_test(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 正则表达式匹配 #[test]
        pattern_test = r'#\s*\[test\]'

        # 遍历内容，找到所有的 #[test] 标记
        matches = list(re.finditer(pattern_test, content))

        # 如果找到了 #[test]，进行处理
        for match in matches:
            start_index = match.start()

            # 从 #[test] 位置开始，寻找第一个 "{"，并继续查找匹配的 "}"
            brace_count = 0
            left_index = start_index

            # 跳过 #[test] 后面的空白字符
            left_index = content.find("{", left_index)

            if left_index == -1:
                continue  # 如果没有找到 '{'，跳过此标记

            # 从第一个 '{' 开始查找匹配的 '}'
            for i in range(left_index, len(content)):
                if content[i] == '{':
                    brace_count += 1
                elif content[i] == '}':
                    brace_count -= 1

                # 当 brace_count 为 0 时，找到了匹配的 '}'
                if brace_count == 0:
                    right_index = i
                    break
            else:
                continue  # 如果没有找到匹配的 '}'，跳过此标记

            # 删除 #[test] 和 { ... } 块的内容
            content = content[:match.start()] + content[right_index + 1:]

        # 将删除后的内容写回原文件
        with open(file_path, 'w', encoding='utf-8') as file:
            file.write(content)

        print(f"已删除文件 {file_path} 中的 #[test] 块及其内容。")

    except FileNotFoundError:
        print(f"文件 {file_path} 未找到。")
    except Exception as e:
        print(f"发生错误: {e}")






def print_single_test(file_path):
    try:
        with open(file_path, 'r', encoding='utf-8') as file:
            content = file.read()

        # 正则表达式匹配 #[test]
        pattern_test = r'#\s*\[test\]'

        # 遍历内容，找到所有的 #[test] 标记
        matches = list(re.finditer(pattern_test, content))

        # 如果找到了 #[test]，进行处理
        for match in matches:
            start_index = match.start()

            # 从 #[test] 位置开始，寻找第一个 "{"，并继续查找匹配的 "}"
            brace_count = 0
            left_index = start_index

            # 跳过 #[test] 后面的空白字符
            left_index = content.find("{", left_index)

            if left_index == -1:
                continue  # 如果没有找到 '{'，跳过此标记

            # 从第一个 '{' 开始查找匹配的 '}'
            for i in range(left_index, len(content)):
                if content[i] == '{':
                    brace_count += 1
                elif content[i] == '}':
                    brace_count -= 1

                # 当 brace_count 为 0 时，找到了匹配的 '}'
                if brace_count == 0:
                    right_index = i
                    break
            else:
                continue  # 如果没有找到匹配的 '}'，跳过此标记

            # 打印 #[test] 和 { ... } 块的内容
            test_block = content[match.start():right_index + 1]
            print(f"找到的测试块: {test_block}\n")

    except FileNotFoundError:
        print(f"文件 {file_path} 未找到。")
    except Exception as e:
        print(f"发生错误: {e}")





'''
input: rust项目路径
output: 执行的测试函数数量
'''
def get_number_of_tests(rust_project_path):
    os.chdir(rust_project_path)
    # 执行 cargo llvm-cov 命令
    result = subprocess.run(['cargo', 'llvm-cov'], capture_output=True, text=True)

    # 获取命令输出
    output = result.stderr + result.stdout
    print(output)
    # 使用正则表达式查找测试数量
    # match = re.search(r'running (\d+) tests', output)
    matches = re.findall(r'running (\d+) tests', output)

    if matches:
        nums = [int(num) for num in matches]
        total = sum(nums)
        return total

    else:
        print("error!!!")
        return -1